/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package pe.gob.foncodes.sega.bs.dao;

import java.io.Serializable;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import org.springframework.stereotype.Repository;
import pe.gob.foncodes.sega.bs.base.dao.DAO;
/**
 *
 * @author Jesus
 */
@Repository
public abstract class AbstractJpaDAO<T, PK extends Serializable> implements
		      DAO<T, PK> {

	@PersistenceContext
	private EntityManager entityManager;
	
	public void setEntityManager(EntityManager entityManager) {
		this.entityManager = entityManager;
	}

	public void save(T paramT) {
		// TODO Auto-generated method stub
		entityManager.persist(paramT);
	}

	public void update(T paramT) {
		// TODO Auto-generated method stub		
		entityManager.merge(paramT);
		entityManager.flush();
	}

	public void delete(T paramT) {
		// TODO Auto-generated method stub
		// entityManager.remove(paramT);
	}

	public T findById(PK paramObject) {
		// TODO Auto-generated method stub
		return entityManager.find(getDomainClass(), paramObject);
	}
	

	

	@SuppressWarnings("unchecked")
	public List<T> find(String paramString) {
		// TODO Auto-generated method stub
		Query query = entityManager.createQuery(paramString);
		return (List<T>) query.getResultList();
	}

	@SuppressWarnings("unchecked")
	public List<T> find(String paramString, Object[] paramArrayOfObject) {
		// TODO Auto-generated method stub
		Query query = entityManager.createQuery(paramString);
		for (int i = 0; i < paramArrayOfObject.length; ++i) {
			query.setParameter((i + 1), paramArrayOfObject[i]);
		}
		return (List<T>) query.getResultList();
	}

	@SuppressWarnings("unchecked")
	public List<T> findNaviteQuery(String paramString) {
		// TODO Auto-generated method stub
		Query query = entityManager.createNativeQuery(paramString,
				getDomainClass());
		return query.getResultList();
	}

	@SuppressWarnings("unchecked")
	public List<T> findNaviteQuery(String paramString,
			Object[] paramArrayOfObject) {
		// TODO Auto-generated method stub
		Query query = entityManager.createNativeQuery(paramString,
				getDomainClass());
		for (int i = 0; i < paramArrayOfObject.length; ++i) {
			query.setParameter((i + 1), paramArrayOfObject[i]);
		}
		return query.getResultList();
	}

	@SuppressWarnings("unchecked")
	public T findUniqueResult(String paramString) {
		// TODO Auto-generated method stub
		Query query = entityManager.createQuery(paramString);
		return (T) query.getSingleResult();
	}

	@SuppressWarnings("unchecked")
	public T findUniqueResult(String paramString, Object[] paramArrayOfObject) {
		// TODO Auto-generated method stub		
		Query query = entityManager.createQuery(paramString);
		for (int i = 0; i < paramArrayOfObject.length; ++i) {
			query.setParameter((i + 1), paramArrayOfObject[i]);
		}
		return (T) query.getSingleResult();
	}

	public Object findUniqueResultObject(String paramString,
			Object[] paramArrayOfObject) {
		// TODO Auto-generated method stub
		Query query = entityManager.createQuery(paramString);
		for (int i = 0; i < paramArrayOfObject.length; ++i) {
			query.setParameter((i + 1), paramArrayOfObject[i]);
		}
		return query.getSingleResult();
	}

	public Object findUniqueResultObject(String paramString) {
		// TODO Auto-generated method stub
		Query query = entityManager.createQuery(paramString);		
		return query.getSingleResult();
	}
	
	@SuppressWarnings("unchecked")
	public List<T> findLimitedResult(String paramString, int paramInt1,
			int paramInt2) {
		// TODO Auto-generated method stub
		Query query = entityManager.createQuery(paramString);
		query.setFirstResult(paramInt1);
		query.setMaxResults(paramInt2);
		return query.getResultList();
	}

	@SuppressWarnings("unchecked")
	public List<T> findLimitedResult(String paramString, int paramInt1,
			int paramInt2, Object[] paramArrayOfObject) {
		// TODO Auto-generated method stub
		Query query = entityManager.createQuery(paramString);
		for (int i = 0; i < paramArrayOfObject.length; ++i) {
			query.setParameter((i + 1), paramArrayOfObject[i]);
		}
		query.setFirstResult(paramInt1);
		query.setMaxResults(paramInt2);
		return query.getResultList();
	}

	public void removeById(PK id) {
		// TODO Auto-generated method stub
		T entity = findById(id);
		if (entity != null) {
			entityManager.remove(entity);
		}
	}

	public void remove(T paramT) {
		// TODO Auto-generated method stub
		entityManager.remove(paramT);
	}

	public abstract Class<T> getDomainClass();


	public Object findNaviteQueryObject(String paramString) {
        Query query = entityManager.createNativeQuery(paramString);                   
        return query.getSingleResult();
  }
	
	public Object findNaviteQueryObject(String paramString,Object[] paramArrayOfObject) {
          Query query = entityManager.createNativeQuery(paramString);          
          if(paramArrayOfObject!=null && paramArrayOfObject.length>0)
        	  for (int i = 0; i < paramArrayOfObject.length; ++i) {
      			query.setParameter((i + 1), paramArrayOfObject[i]);
      		} 
          try{
        	  return query.getSingleResult();
          }
          catch(NoResultException e){        	  
        	  return null;
          }
    }

	public List<Object[]> findNaviteQueryListObject(String paramString, 
			Object[] paramArrayOfObject) {
        Query query = entityManager.createNativeQuery(paramString);
        if(paramArrayOfObject!=null)
        for (int i = 0; i < paramArrayOfObject.length; ++i) {
			query.setParameter((i + 1), paramArrayOfObject[i]);
			System.out.println("Parameter:::> "+(i + 1)+" , "+paramArrayOfObject[i]);
		}
        System.out.println("SQL:::> "+paramString);
        return query.getResultList();
  }
	
	public List<Object[]> findNaviteQueryListObject(String paramString) {
        Query query = entityManager.createNativeQuery(paramString);
        System.out.println("SQL:::> "+paramString);
        return query.getResultList();
  }
	
	public Object executeNaviteQueryObject(String paramString) {
        Query query = entityManager.createNativeQuery(paramString);          
        return query.executeUpdate();
  }
    public Object executeNaviteQueryObject(String paramString,Object[] paramArrayOfObject) {
        Query query = entityManager.createNativeQuery(paramString);
        
        	if(paramArrayOfObject!=null)
            for (int i = 0; i < paramArrayOfObject.length; ++i) {
    			query.setParameter((i + 1), paramArrayOfObject[i]);    			
    		}
        	
        return query.executeUpdate();
  }

}